package com.dems.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dems.core.enumerate.ResEnum;
import com.dems.core.exception.LoanassistRuntimeException;
import com.dems.core.util.*;
import com.dems.dao.dataobject.*;
import com.dems.dao.mapper.la.MenuMapper;
import com.dems.dao.mapper.la.StaffRoleMapper;
import com.dems.dao.mapper.la.UserMapper;
import com.dems.dao.mapper.la.VcodeMapper;
import com.dems.domain.*;
import com.dems.domain.enumerate.UserTypeEnum;
import com.dems.domain.org.DeptStaffDto;
import com.dems.domain.upload.FileUploadDto;
import com.dems.domain.user.UserBasicMessageVO;
import com.dems.domain.user.UserDto;
import com.dems.remote.ali.OssUtil;
import com.dems.remote.ali.SmsUtil;
import com.dems.service.IUserService;
import com.dems.service.org.manager.StaffManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
@RefreshScope
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private FactoryService factoryService;

    @Autowired
    private SmsUtil smsUtil;

    @Autowired
    private VcodeMapper vcodeMapper;

    @Autowired
    private StaffRoleMapper staffRoleMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private StaffManager staffManager;

    @Value("${la.config.defaultPwd}")
    private String DEFAULT_PWD;

    @Value("${la.config.partnerId:0}")
    private Long LA_CONFIG_PARTNERID;

    @Value("${ali.sms.templateCode}")
    private String ALI_SMS_TEMPLATECODE;

    @Autowired
    private OssUtil ossUtil;



    @Override
    public JSONObject getPartner(ReqBaseVO reqBaseVO) {
        User user = userMapper.selectByOpenId(reqBaseVO.getOpenId());
        if (user == null) {
            return null;
        }

        if (StringUtils.isEmpty(user.getPartnerCode())) {
            return null;
        }

        JSONObject data = new JSONObject();

        data.put("partnerCode", user.getPartnerCode());
        data.put("name", user.getName());

        return data;

    }

    /**
     * 根据openid partnerCode 获取下级openId列表
     *
     * @param openId
     * @return
     */
    @Override
    public List<String> subOpenIds(String openId, List<String> partnerCode, int level) {
        List<String> openIds = new ArrayList<>();
        if (StringUtils.isNotBlank(openId)) {
            openIds.add(openId);
        }
        if (partnerCode == null || partnerCode.isEmpty()) {
            return openIds;
        }
        List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("invite_code", partnerCode)
                                                                            .or()
                                                                            .in(level == 2, "parent_invite_code",
                                                                                            partnerCode)
                                                                            .or()
                                                                            .in("partner_code", partnerCode));
        if (userList == null) {
            return openIds;
        }
        // 当前openId 获取到的子openId
        openIds.addAll(userList.stream().map(User::getOpenId).collect(Collectors.toList()));
        return openIds;
    }

    /**
     * 修改密码
     *
     * @param user
     * @param modifyPasswordReqVO
     */
    @Override
    public void modifyPwd(User user, ModifyPasswordReqVO modifyPasswordReqVO) {
        User dbUser = null;
        if(user.getOpenId() != null) {
            dbUser = userMapper.selectByOpenId(user.getOpenId());
        }else {
            dbUser = userMapper.selectByPrimaryKey(user.getUserId());
        }
        //        if (!modifyPasswordReqVO.getLastPassword().equalsIgnoreCase(dbUser.getPassword())) {
        //            throw new FastUserException("旧密码不匹配！");
        //        }
        dbUser.setPassword(modifyPasswordReqVO.getNewPassword());
        userMapper.updateByPrimaryKeySelective(dbUser);
    }

    @Override
    public Page<UserVO> fetchUserList(User user, UserReqVO userReqVO)
                    throws InvocationTargetException, IllegalAccessException {

        // 非代理用户
        if (user.getPartnerCode() == null) {
            return null;
        }
        // 判断是否为总部用户、名单管理员
        if (UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.T, UserTypeEnum.NM,
                        UserTypeEnum.F, UserTypeEnum.BIZ_FRONT)) {
            user.setPartnerCode(null);
        }

        log.info("login userInfo {}", JSON.toJSONString(user));

        if (UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.M)) {
            userReqVO.setPartnerCodeList(buildL1UserPartnerCode(user));
            user.setPartnerCode(null);
        }

        if (UserTypeEnum.checkTypeRole(userReqVO.getUserType(), user.getRoleCodeList(), UserTypeEnum.L2)) {
            userReqVO.setUserTypeList(Arrays.asList(UserTypeEnum.L2.getCode(), UserTypeEnum.T.getCode()));
            userReqVO.setUserType(null);
        }

        // 1级代理
        Page<User> userL1List = (Page<User>) userMapper.selectParentList(
                        new Page<User>(userReqVO.getPageNum(), userReqVO.getPageSize()), user.getPartnerCode(),
                        userReqVO.getName(), userReqVO.getPhoneNo(), userReqVO.getLevel(), userReqVO.getUserType(),
                        userReqVO.getUserTypeList(), userReqVO.getPartnerCodeList());

        // 下属相关信息

        List<UserVO> userVOListL1 = new ArrayList<>();

        if (userL1List != null && !userL1List.getRecords().isEmpty()) {
            List<StaffRole> staffRoleList = staffRoleMapper.selectByUserIdList(
                            userL1List.getRecords().stream().map(User::getUserId).collect(Collectors.toList()));

            Map<String, StaffRole> staffRoleMap = staffRoleList.stream()
                                                               .collect(Collectors.toMap(StaffRole::getUserId,
                                                                               Function.identity(),
                                                                               (key1, key2) -> key1));

            for (User item : userL1List.getRecords()) {
                UserVO userVO = new UserVO();
                BeanUtils.copyProperties(item, userVO);
                if (StringUtils.isNotBlank(item.getProfile())) {
                    JSONObject profileJson = JSONObject.parseObject(item.getProfile());
                    userVO.setSipAccount(profileJson.getString("sipAccount"));
                    if(profileJson.get("number") != null){
                        userVO.setNumber(profileJson.getString("number"));
                    }
                }

                if (staffRoleMap.containsKey(item.getUserId())) {
                    userVO.setRoleCodeList(Arrays.asList(staffRoleMap.get(item.getUserId()).getStaffRole().split(",")));
                }

                userVOListL1.add(userVO);
            }
        }

        Page<UserVO> data = new Page<>();
        BeanUtils.copyProperties(userL1List, data);
        data.setRecords(userVOListL1);
        return data;
    }

    @Override
    public Page<DeptStaffDto> fetchUserListV2(User user, UserReqVO userReqVO)
                    throws InvocationTargetException, IllegalAccessException {

        // 非代理用户
        if (user.getPartnerCode() == null) {
            return null;
        }
        // 判断是否为总部用户、名单管理员
        if (UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.T, UserTypeEnum.NM,
                        UserTypeEnum.F, UserTypeEnum.BIZ_FRONT, UserTypeEnum.HR)) {
            user.setUserId(null);
        }

        log.info("login userInfo {}", JSON.toJSONString(user));

        if (UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.M)||
                UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.C)
                ||UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.V)
                ||UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.VL)
                ||UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.L1)) {
            userReqVO.setSupervisorIdsList(buildL1UserIdList(user));
            user.setUserId(null);
        }

        if (UserTypeEnum.checkTypeRole(userReqVO.getUserType(), user.getRoleCodeList(), UserTypeEnum.L2)) {
            userReqVO.setRoleCodeList(Arrays.asList(UserTypeEnum.L2.getCode(), UserTypeEnum.T.getCode()));
        }

        Page<DeptStaff> deptStaffPage = staffManager.fetchUser(userReqVO, user);

        Page<DeptStaffDto> data = new Page<>();
        BeanUtils.copyProperties(deptStaffPage, data);
        if (CollectionUtils.isNotEmpty(deptStaffPage.getRecords())) {
            deptStaffPage.getRecords().forEach(item -> {
                if (StringUtils.isNotBlank(item.getStaffRole())) {
                    item.setRoleCodeList(Arrays.asList(item.getStaffRole().split(",")));
                }
                if (StringUtils.isNotBlank(item.getProfile())) {
                    JSONObject profileJson = JSONObject.parseObject(item.getProfile());
                    item.setSipAccount(profileJson.getString("sipAccount"));
                    item.setGid(profileJson.getLong("gid"));
                    if(profileJson.get("number") != null){
                        item.setNumber(profileJson.getString("number"));
                    }
                }
            });
            List<DeptStaffDto> deptStaffDtoList =
                            BeanCopyUtils.copyListProperties(deptStaffPage.getRecords(), DeptStaffDto::new);
            data.setRecords(deptStaffDtoList);

        }

        return data;
    }

    @Override
    public Page<DeptStaffDto> fetchAllUserList(UserReqVO userReqVO) {
        Page<DeptStaff> deptStaffPage = staffManager.fetchUser(userReqVO, new User());
        Page<DeptStaffDto> data = new Page<>();
        BeanUtils.copyProperties(deptStaffPage, data);
        if (CollectionUtils.isNotEmpty(deptStaffPage.getRecords())) {
            deptStaffPage.getRecords().forEach(item -> {
                if (StringUtils.isNotBlank(item.getStaffRole())) {
                    item.setRoleCodeList(Arrays.asList(item.getStaffRole().split(",")));
                }
                if (StringUtils.isNotBlank(item.getProfile())) {
                    JSONObject profileJson = JSONObject.parseObject(item.getProfile());
                    item.setSipAccount(profileJson.getString("sipAccount"));
                    item.setGid(profileJson.getLong("gid"));
                    if(profileJson.get("number") != null){
                        item.setNumber(profileJson.getString("number"));
                    }
                }
            });
            List<DeptStaffDto> deptStaffDtoList =
                    BeanCopyUtils.copyListProperties(deptStaffPage.getRecords(), DeptStaffDto::new);
            data.setRecords(deptStaffDtoList);

        }
        return data;
    }

    public void downLoadPartnerListV2(User user, UserReqVO userReqVO) throws InvocationTargetException, IllegalAccessException {
        // 非代理用户
        if (user.getPartnerCode() == null) {
            return;
        }
        // 判断是否为总部用户、名单管理员
        if (UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.T, UserTypeEnum.NM,
                UserTypeEnum.F, UserTypeEnum.BIZ_FRONT, UserTypeEnum.HR)) {
            user.setUserId(null);
        }

        log.info("login userInfo {}", JSON.toJSONString(user));

        if (UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.M)) {
            userReqVO.setSupervisorIdsList(buildL1UserIdList(user));
            user.setUserId(null);
        }

        if (UserTypeEnum.checkTypeRole(userReqVO.getUserType(), user.getRoleCodeList(), UserTypeEnum.L2)) {
            userReqVO.setRoleCodeList(Arrays.asList(UserTypeEnum.L2.getCode(), UserTypeEnum.T.getCode()));
        }
    }
    private List<String> buildL1UserPartnerCode(User user) {
        List<String> l1UserPartnerCode = new ArrayList<>();

        Set<String> codeSet = new HashSet<>();
        codeSet.add(user.getPartnerCode());
        List<User> l1UserList = userMapper.selectUserByInviteCode(codeSet);

        l1UserPartnerCode.add(user.getPartnerCode());

        if (l1UserList != null) {
            for (User item : l1UserList) {
                l1UserPartnerCode.add(item.getPartnerCode());
            }
        }

        return l1UserPartnerCode;
    }

    private List<String> buildL1UserIdList(User user) {
        List<Dept> subDeptList = staffManager.fetchOwnDept(user.getUserId());

        if (CollectionUtils.isEmpty(subDeptList)) {
            return new ArrayList<>();
        }

        return subDeptList.stream()
                          .map(Dept::getSupervisorIds)
                          .filter(StringUtils::isNotBlank)
                          .distinct()
                          .collect(Collectors.toList());
    }

    /**
     * 支持openId和userId
     * @param openId
     * @return
     */
    @Override
    public User fetchUser(String openId) {
        User user = userMapper.selectByOpenId(openId);

        // 补充权限code和菜单code,根据所属呼叫中心补充profile
        if (user != null) {
            List<StaffRole> staffRoleList = staffRoleMapper.selectByUserId(user.getUserId());
            if (CollectionUtils.isNotEmpty(staffRoleList)) {
                user.setRoleCodeList(staffRoleList.stream().map(StaffRole::getRoleCode).collect(Collectors.toList()));
            }

            if (CollectionUtils.isNotEmpty(staffRoleList)) {
                List<String> roleCodeList =
                                staffRoleList.stream().map(StaffRole::getRoleCode).collect(Collectors.toList());
                List<String> userTypeList = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(roleCodeList)) {
                    userTypeList.addAll(roleCodeList);
                }
                List<Menu> menuList = menuMapper.selectByRoleCode(userTypeList);
                if (CollectionUtils.isNotEmpty(menuList)) {
                    user.setMenuCodeList(menuList.stream().map(Menu::getMenuCode).collect(Collectors.toList()));
                }
            }
        }

        return user;

    }

    /**
     * 发送短信验证码
     *
     * @param bindPartnerReqVO
     * @throws Exception
     */
    @Override
    public void sendVcode(BindPartnerReqVO bindPartnerReqVO) throws Exception {
        Vcode vcode = vcodeMapper.selectByPhoneNo(bindPartnerReqVO.getPhoneNo());

        if (null != vcode && DateUtils.addMinutes(new Date(), -1).getTime() < vcode.getExpireTime().getTime()) {
            throw new LoanassistRuntimeException("验证码还在有效期内，请勿频繁点击");
        }

        User user = userMapper.selectByOpenId(bindPartnerReqVO.getOpenId());
        if (user == null) {
            throw new LoanassistRuntimeException("用户信息异常，请刷新");
        }

        String vcodeStr = SerialNoUtil.generateCodeDefault();

        JSONObject param = new JSONObject();
        param.put("code", vcodeStr);

        smsUtil.doSendSms(bindPartnerReqVO.getPhoneNo(), ALI_SMS_TEMPLATECODE, param.toJSONString());

        vcode = new Vcode();
        vcode.setPhoneNo(bindPartnerReqVO.getPhoneNo());
        vcode.setVcode(vcodeStr);
        vcode.setExpireTime(DateUtils.addMinutes(new Date(), 5));
        vcode.setCreateOpenId(user.getOpenId());
        vcode.setCreateUserId(user.getUserId());
        vcode.setCreateTime(new Date());
        vcodeMapper.insert(vcode);
    }

    /**
     * 设置用户类型，默认坐席
     *
     * @param user
     * @param userReqVO
     * @return
     */
    @Override
    public User modifyUserType(User user, UserReqVO userReqVO) {

        if (!UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.L1, UserTypeEnum.VL, UserTypeEnum.BIZ_VISIT_L,
                        UserTypeEnum.T, UserTypeEnum.M)) {
            throw new LoanassistRuntimeException("用户权限异常，请核实");
        }

        User modifyUser = userMapper.selectByPrimaryKey(userReqVO.getUserId());

        if (!modifyUser.getUserType().equalsIgnoreCase(userReqVO.getFromUserType()) || (
                        UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.L1,
                                        UserTypeEnum.VL, UserTypeEnum.BIZ_VISIT_L)
                                && staffManager.checkBelong(user.getUserId(), modifyUser.getUserId())
                                && !UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.T, UserTypeEnum.VL, UserTypeEnum.BIZ_VISIT_L)
        )) {
            throw new LoanassistRuntimeException("用户类型不匹配，请核实");
        }

        modifyUser.setUserType(userReqVO.getUserType());
        modifyUser.setStatus(0);

        if (StringUtils.isBlank(modifyUser.getPassword())) {
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            modifyUser.setPassword(encoder.encode(DEFAULT_PWD));
        }

        userMapper.updateByPrimaryKeySelective(modifyUser);

        return modifyUser;
    }

    /**
     * 员工离职
     *
     * @param user
     * @param userReqVO
     * @return
     */
    @Override
    public User fireUser(User user, UserReqVO userReqVO) {
        if (!UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.L1, UserTypeEnum.VL, UserTypeEnum.BIZ_VISIT_L,
                        UserTypeEnum.T, UserTypeEnum.M)) {
            throw new LoanassistRuntimeException("用户权限异常，请核实");
        }

        User modifyUser = userMapper.selectByPrimaryKey(userReqVO.getUserId());
        //modifyUser.getStatus() != 0 去掉离职员工操作限制
        if (!UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.T, UserTypeEnum.VL, UserTypeEnum.BIZ_VISIT_L)
                && (UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.L1,
                                        UserTypeEnum.VL, UserTypeEnum.BIZ_VISIT_L) && !staffManager.checkBelong(user.getUserId(),
                                        modifyUser.getUserId()))) {
            throw new LoanassistRuntimeException("用户类型不匹配，请核实");
        }
        modifyUser.setStatus(-1);
        modifyUser.setPassword("");
        modifyUser.setUserType("-" + modifyUser.getUserType());
        userMapper.updateByPrimaryKeySelective(modifyUser);

        return modifyUser;
    }

    @Override
    public User deactivateUser(User user, UserReqVO userReqVO) {
        if (!UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(), UserTypeEnum.T)) {
            throw new LoanassistRuntimeException("用户权限异常，请核实");
        }

        User modifyUser = userMapper.selectByPrimaryKey(userReqVO.getUserId());

        if (modifyUser.getStatus() != 0 || !UserTypeEnum.checkTypeRole(user.getUserType(), user.getRoleCodeList(),
                        UserTypeEnum.V, UserTypeEnum.BIZ_VISIT)) {
            throw new LoanassistRuntimeException("用户类型不匹配，只能注销接待，请核实");
        }

        modifyUser.setStatus(-1);
        modifyUser.setPassword("");
        modifyUser.setOpenId("-" + modifyUser.getOpenId());
        modifyUser.setPartnerCode("-" + modifyUser.getPartnerCode());
        modifyUser.setPhoneNo("-" + modifyUser.getPhoneNo());
        modifyUser.setUserType("-" + modifyUser.getUserType());
        userMapper.updateByPrimaryKeySelective(modifyUser);

        return modifyUser;
    }

    /**
     * 保存sip 外呼账号信息
     *
     * @param userReqVO
     * @param loanassistUser
     * @return
     */
    @Override
    public int saveSipInfo(UserReqVO userReqVO, User loanassistUser) {

        JSONObject profileJson = new JSONObject();

        loanassistUser = userMapper.selectByPrimaryKey(loanassistUser.getUserId());

        String profile = loanassistUser.getProfile();

        if (StringUtils.isNotBlank(profile)) {
            profileJson = JSONObject.parseObject(profile);
        }

        if (StringUtils.isNotBlank(userReqVO.getSipAccount())) {
            User userInfo = userMapper.selectBySipAccount(userReqVO.getSipAccount(), userReqVO.getCallCenter());
            if(userInfo != null && !userInfo.getUserId().equals(loanassistUser.getUserId())){
                throw new LoanassistRuntimeException(ResEnum.DUP_DATA, "私有账号数据重复,请核实!");
            }
            profileJson.put("sipAccount", userReqVO.getSipAccount());
            profileJson.put("sipPassword", userReqVO.getSipPassword());
        }

        if (StringUtils.isNotBlank(userReqVO.getSipToken())) {
            profileJson.put("sipToken", userReqVO.getSipToken());
            profileJson.put("sipTokenExpire", userReqVO.getSipTokenExpire());
        }

        if(StringUtils.isNotBlank(userReqVO.getDisplayName())){
            profileJson.put("displayNmae", userReqVO.getDisplayName());
        }

        if(StringUtils.isNotBlank(userReqVO.getDirectNumber())){
            profileJson.put("directNumber", userReqVO.getDirectNumber());
        }

        if(userReqVO.getCallTime() != null){
            profileJson.put("callTime", userReqVO.getCallTime());
        }

        if(userReqVO.getNumber() != null){
            profileJson.put("number", userReqVO.getNumber());
        }

        if(userReqVO.getGid() != null){
            profileJson.put("gid", userReqVO.getGid());
        }

        loanassistUser.setProfile(profileJson.toJSONString());

        return userMapper.updateProfileByPrimaryKey(loanassistUser);
    }

    /**
     * 获取待分配用户列表
     *
     * @param userReqVO
     * @param loanassistUser
     */
    public List<UserVO> fetchAllocateUserList(UserReqVO userReqVO, User loanassistUser) {
        // 校验权限是否正常
        if (!UserTypeEnum.checkTypeRole(loanassistUser.getUserType(), loanassistUser.getRoleCodeList(), UserTypeEnum.T,
                        UserTypeEnum.F, UserTypeEnum.BIZ_FRONT, UserTypeEnum.M, UserTypeEnum.VL, UserTypeEnum.BIZ_VISIT_L, UserTypeEnum.V, UserTypeEnum.BIZ_VISIT)) {
            throw new LoanassistRuntimeException("无权限");
        }

        List<StaffRole> staffRoleList = staffRoleMapper.selectByRoleCode(
                        Arrays.asList(UserTypeEnum.V.getCode(), UserTypeEnum.VL.getCode(), UserTypeEnum.T.getCode()));

        List<User> userList = userMapper.selectByIdList(
                        staffRoleList.stream().map(StaffRole::getUserId).distinct().collect(Collectors.toList()));

        List<UserVO> userVOList = JSONArray.parseArray(JSON.toJSONString(userList), UserVO.class);

        //        BeanUtils.copyProperties(userList, userVOList);

        return userVOList;
    }

    public JSONObject sendUserInfo(UserReqVO userReqVO, User loanassistUser) {
        JSONObject data = new JSONObject();
        data.put("userId", loanassistUser.getUserId());
        data.put("name", loanassistUser.getName());
        return data;
    }

    /**
     * 根据openId 获取用户信息
     * 根据用户信息获取权限codeList
     *
     * @param reqBaseVO
     * @return
     */
    @Override
    public List<String> fetchRoleCodeList(ReqBaseVO reqBaseVO) {
        User user = userMapper.selectByOpenId(reqBaseVO.getOpenId());

        if (user == null) {
            return new ArrayList<>();
        }

        List<StaffRole> staffRoleList = staffRoleMapper.selectByUserId(user.getUserId());

        if (CollectionUtils.isEmpty(staffRoleList)) {
            return new ArrayList<>();
        }

        return staffRoleList.stream().map(StaffRole::getRoleCode).distinct().collect(Collectors.toList());
    }

    /**
     * 新增用户
     *
     * @param userReqVO
     * @param loanassistUser
     * @return
     */
    @Override
    public User addUser(UserReqVO userReqVO, User loanassistUser) {

        if (!UserTypeEnum.checkTypeRole(loanassistUser.getUserType(), loanassistUser.getRoleCodeList(), UserTypeEnum.T,
                        UserTypeEnum.M)) {
            throw new LoanassistRuntimeException("新增用户类型异常，添加人员角色不匹配");
        }

        User user = userMapper.selectByPhoneNo(userReqVO.getPhoneNo());

        if (null != user) {
            throw new LoanassistRuntimeException("添加用户已存在，请检查");
        }

        user = new User();

        String userId = factoryService.createIdByObj(User.class);

        String partnerCode = Encode64Util.compressNumber(Long.valueOf(userReqVO.getPhoneNo()));

        user.setUserId(userId);
        user.setUserType(UserTypeEnum.L2.getCode());
        user.setPartnerCode(partnerCode);
        user.setName(userReqVO.getName());
        user.setPhoneNo(userReqVO.getPhoneNo());
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        user.setPassword(encoder.encode(DEFAULT_PWD));
        user.setBuId(LA_CONFIG_PARTNERID.intValue());

        userMapper.insertSelective(user);

        return user;
    }

    @Override
    public String updateBasicMessage(UserBasicMessageVO userBasicMessageVO) {
        FileUploadDto fileUploadDto = new FileUploadDto();
        BeanUtils.copyProperties(userBasicMessageVO, fileUploadDto);
        User user = new User();
        String url = "";
        BeanUtils.copyProperties(userBasicMessageVO, user);
        user.setUserId(userBasicMessageVO.getUserId());
        if(fileUploadDto.getBase64Content() != null) {
            url = ossUtil.uploadFile(fileUploadDto);
            user.setHeadimgUrl(url);
        }
        this.userMapper.updateByPrimaryKeySelective(user);
        return url;
    }

    @Override
    public Integer clearSipInfo(UserReqVO userReqVO){
        JSONObject profileObject = new JSONObject();
        User loanassistUser = userMapper.selectByPrimaryKey(userReqVO.getUserId());
        loanassistUser.setProfile(profileObject.toJSONString());
        return userMapper.updateProfileByPrimaryKey(loanassistUser);
    }

    @Override
    public void resetPwd(ModifyPasswordReqVO modifyPasswordReqVO) {
        User dbUser = userMapper.selectByPrimaryKey(modifyPasswordReqVO.getUserId());
        if(dbUser != null){
            dbUser.setPassword(modifyPasswordReqVO.getNewPassword());
            userMapper.updateByPrimaryKeySelective(dbUser);
        }
        else {
            throw new LoanassistRuntimeException(ResEnum.USER_INFO_ERROR, "当前用户不存在,请核对!");
        }
    }

    /**
     * 修改用户所属机构
     * @param user
     * @param userId
     * @param buId
     * @return
     */
    @Override
    public Integer updateBuId(User user, String userId, Integer buId) {


        return null;
    }

    @Override
    public Integer updateUser(User user, UserReqVO userReqVO) {
        User dbUser = userMapper.selectByPrimaryKey(userReqVO.getUserId());
        Integer status = 1;
        if(dbUser != null){
            if(dbUser.getProfile() != null && userReqVO.getSipAccount() != null){
                JSONObject object = JSONObject.parseObject(dbUser.getProfile());
                object.put("sipAccount", userReqVO.getSipAccount());
                dbUser.setProfile(object.toJSONString());
            }
            if(userReqVO.getOpenId() != null){
                dbUser.setOpenId(userReqVO.getOpenId());
            }
            if(userReqVO.getBuId() != null){
                dbUser.setBuId(userReqVO.getBuId());
            }
            if(userReqVO.getCreditAccount() != null){
                dbUser.setCreditAccount(userReqVO.getCreditAccount());
            }
            status =userMapper.updateByPrimaryKeySelective(dbUser);
            if(userReqVO.getIsDelete() == 1){
              status = userMapper.deleteByPrimaryKey(userReqVO.getUserId());
            }
        }
        return status;
    }

    @Override
    public UserDto findUserById(UserReqVO userReqVO) {
        User user = staffManager.fetchUserInfoWithL1(userReqVO.getUserId());
        user.setPhoneNo(DataFactory.toConceal(user.getPhoneNo()));
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(user, userDto);
        List<String> userIdList = new ArrayList<>();
        userIdList.add(user.getUserId());
        String userType = user.getUserType();
        //有上级主管则查询个人统计信息
        if(userType.equals(UserTypeEnum.VL.getCode()) || userType.equals(UserTypeEnum.L1)){
            List<DeptStaff> deptStaffList = staffManager.getDirectSubDeptUser(userIdList);
            deptStaffList.forEach(deptStaff -> {
                userIdList.add(deptStaff.getUserId());
            });
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        Date startTime = new Date();
        Calendar cal =Calendar.getInstance();
        cal.add(Calendar.MONTH, -12);
        String endDate = format.format(startTime);
        String startDate = format.format(cal.getTime());
        List<Map<String,Object>> resultMap = userMapper.selectRepayInfoByUser(userIdList,startDate,endDate);
        List<JSONObject> comissionMountList = new ArrayList<>();
        while(cal.getTime().before(startTime)){
            JSONObject object = new JSONObject();
            resultMap.forEach(map ->{
                String tempDate = format.format(cal.getTime());
                if(map.get("countTime") != null && map.get("countTime").equals(tempDate)){
                    object.put("comissionMount", map.get("comissionMount"));
                }
            });
            object.put("countTime", format.format(cal.getTime()));
            if(object.get("comissionMount") == null){
                object.put("comissionMount", 0);
            }
            comissionMountList.add(object);
            cal.add(Calendar.MONTH, 1);
        }
        userDto.setComissionMountList(comissionMountList);
        return userDto;
    }
}
